'''
Created on 30 Nov 2012

@author: quirino.brizi
'''
from .connectionpool import HTTPConnectionPool, AsyncHTTPConnectionPool
from defaults import pool
from utils import merge
from types import ListType, TupleType

debug = False

class Session(object):
    '''
    Request session enable context-management
    '''

    def __init__(self, config={}, async=False):
        '''
        Initialises a new session
        @param config: the session configuration as a dict. 
        i.e. {'pool':{'host':'http:myhost.my', port:8080, 'maxsize:10'}}. 
        Complete list of parameters for connection pool configuration is:
         * host: the remote host name
         * port: the remote host port
         * maxsize: the maximum pool size
         * block: pool blocking policy definition, True the pool will wait 
           if a connection is not available, False the request is not performed 
           if a connection is not available
         * timeout: the timeout the pool should wait for a connection in 
           there internal queue is empty
        the configuration parameters are merged with a default giving precedence 
        to the provided
        '''
        if "pool" in config :
            poolconf = merge(pool, config["pool"])
        else :
            poolconf = pool
        if not async:
            self.pool = HTTPConnectionPool(**poolconf)
        else:
            self.pool = AsyncHTTPConnectionPool(**poolconf)
        self.async = async
        self.closed = False

    def exchange(self, requests):
        """
        Exchanges request-response messages between requester an replier.
        @param requests: a list of request message object as defined on 
        messages module
        @return: the list of replier Response message as defined on 
        messages module if the session has been initialized as synchronous, 
        a list of Futures is the session has been initialized as asynchronous
        """
        if self.async:
            return self.pool.urlopen(requests)
        else:
            responses = []
            if isinstance(requests, (ListType, TupleType)):
                for request in requests:
                    responses.append(self.pool.urlopen(request))
            else:
                responses.append(self.pool.urlopen(requests))
            return responses
    
    def close(self):
        """
        Close the current session and release all the resources.
        """
        self.closed = True
        self.pool.close()
    
    def is_closed(self):
        """
        Verify the session status.
        @return: True if the session is closed, False otherwise.
        """
        return self.closed
        
def session(): 
    """
    Return a default session
    """
    return Session()
